/***************************************** 
 *
 * Listing 1.2
 *
 * Example performing I/O on s socket pair:
 * 
 * ******************************************/ 
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>

// for socketpair sendmsg/recvmsg
typedef struct {
     unsigned int  command;
     pid_t   pid;
     int   slot;
     FILE  *fd;
} http_channel_t;

int http_write_channel(int sock, char *send_buf, int send_len)
{
    struct msghdr msg;
    struct iovec iov[1];        
    
    bzero(&msg, sizeof(msg));
    msg.msg_name = NULL;        /* attention this is a pointer to void* type */
    msg.msg_namelen = 0;         
        
    iov[0].iov_base = send_buf;
    iov[0].iov_len = send_len;
    
    msg.msg_iov = iov;
    msg.msg_iovlen = 1;        

    return sendmsg( sock, &msg, 0 );
}


int http_read_channel(int sock, char *recv_buf, int recv_len)
{
    struct msghdr msgr;
    struct iovec iovr[1];      
      
    bzero(&msgr, sizeof(msgr));
    bzero(recv_buf, recv_len);
    
    msgr.msg_name = NULL;        // attention this is a pointer to void* type
    msgr.msg_namelen = 0;
        
    iovr[0].iov_base = (char*) recv_buf;
    iovr[0].iov_len = recv_len;
    
    msgr.msg_iov = iovr;    
    msgr.msg_iovlen = 1; 

    return recvmsg(  sock, &msgr, 0);               
}


int process()
{
    int z;        /* Status return code */
    int s[2];    /* Pair of sockets */
    pid_t pid;
    
    z = socketpair(AF_LOCAL,SOCK_STREAM,0,s);
    pid = fork();

    if (pid>0) {//parent    
        /*
        * Sendmsg to Socket s[1]:
        */            
        char send_buf[100] = "abcdefghijk";
        
        for ( ; ; ) {
            z = http_write_channel(s[0], send_buf, strlen(send_buf));
            sleep(1);
        }
        
    }
    else if (pid==0) {//son                
        /*
         * Read from socket s[0]:
         */        
        char recv_buf[100];
        
        for ( ; ; ) {
            z = http_read_channel(s[1], recv_buf, sizeof(recv_buf));        
            printf("recvmsg : %s, size : %d, pid : %d \n", recv_buf, sizeof(recv_buf), getpid() );
            sleep(1);
        }
    }
    else {
        printf("Fork error!\n");
    }

    return 0;
}

int main(int argc,char **argv)
{
    int status;       
    
    for (int i=0; i<2; i++) {
        process();
    }
    
    wait( &status );
    return 0;
}
